/*
 * Copyright 2008 Lucas Tan.
 * This copyright notice must always remain intact whenever you use or distribute 
 * the source code contained in this file.
 * Any usage of any code in this file, either in derived work or
 * through the use of external linkage,
 * must always be credited with the author's name.
 * 
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 * 
 * */
using System;
using System.Collections.Generic;
using System.Text;
using G11N = System.Globalization;
using Microsoft.Win32;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using PassKeeper.Properties;

namespace PassKeeper.Gui
{
	/// <summary>
	/// Internal utility class that manages localized resources.
	/// </summary>
	internal static class Util
	{

		private static G11N.CultureInfo s_cultureInfo;
		private static object s_lock;

		static Util()
		{
			s_lock = new object();
			s_cultureInfo = G11N.CultureInfo.ReadOnly(G11N.CultureInfo.CurrentUICulture);
			
			/*Makes resource IDs lookup case sensitive.*/
			Resources.ResourceManager.IgnoreCase = false;
		}

		internal static string Format(int num)
		{
			return num.ToString(s_cultureInfo.NumberFormat);
		}

		internal static string GetResourceString(string id)
		{
			try
			{
				return Resources.ResourceManager.GetString(id);
			}
			catch 
			{
				/* Return the id string itself if we cannot
				 * load the resource string. At least there's
				 something to show the user. */
				return id;
			}
		}

		internal static string FormatResourceString(string id, params object[] args)
		{
			return string.Format(GetResourceString(id), args);
		}

		internal static bool IsCultureInfoSupported(G11N.CultureInfo cultureInfo)
		{
			/*Right now, we don't support other type of localization.*/
			return false;
		}

		internal static G11N.CultureInfo CultureInfo
		{
			get
			{
				return s_cultureInfo;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				
				lock (s_lock)
				{
					s_cultureInfo = G11N.CultureInfo.ReadOnly(value);
				}
			}
		}

		private static void SetFontHelper(Control ctl)
		{
			foreach (Control child in ctl.Controls)
			{
				child.Font = SystemFonts.MessageBoxFont;
				SetFontHelper(child);
			}
		}

		/// <summary>
		/// Sets the font of a specified control and all of its descendants to the system default dialog font.
		/// </summary>
		/// <param name="ctl">A control whose font and that of its descendants will be set to the system default dialog font.</param>
		/// <exception cref="System.ArgumentNullException"><paramref name="ctl"/> is <c>null</c>.</exception>
		internal static void SetFont(Control ctl)
		{
			if (ctl == null)
			{
				throw new ArgumentNullException("ctl");
			}

			ctl.Font = SystemFonts.MessageBoxFont;

			SetFontHelper(ctl);

			if (ctl is ContainerControl)
			{
				((ContainerControl) ctl).AutoScaleMode = AutoScaleMode.Font;
				((ContainerControl) ctl).PerformAutoScale();
			}
		}

		internal static bool Browse(Uri uri)
		{
			/*Todo: check for insecure URI.*/

			if (uri == null)
			{
				throw new ArgumentNullException("uri");
			}

			if (!uri.IsAbsoluteUri)
			{
				throw new ArgumentException("Must be absolute.", "uri");
			}

			/*The preferred method is this.*/
			try
			{
				Process.Start(uri.OriginalString);
				return true;
			}
			catch
			{
				/*do nothing.*/
			}

			/*Fallback to the next method.*/

			string cmd = GetDefaultBrowserCommand();

			/*The command string looks something like:
			 "C:\program files\Internet Explorer\iexplore.exe" -args -url "%1"
			 * or
			 * C:\PROGRA~1\MOZILL~1\FIREFOX.EXE -requestPending -osint -url "%1"
			 * 
			 * where %1 is the URL to open.
			 */

			if (!string.IsNullOrEmpty(cmd))
			{

				string exePath = null;
				string args = null;

				if (cmd[0] == '"')
				{
					int i = cmd.IndexOf('"', 1);

					if (i >= 1)
					{
						exePath = cmd.Substring(1, i - 1);
						args = cmd.Substring(i + 1).Trim();
					}
				}
				else
				{
					int i = cmd.IndexOf(' ');

					if (i >= 0)
					{
						exePath = cmd.Substring(0, i);
						args = cmd.Substring(i + 1).Trim();
					}
					else
					{
						exePath = cmd;
						args = "%1";
					}
				}

				if (!string.IsNullOrEmpty(exePath))
				{
					if (!File.Exists(exePath))
					{
						return false;
					}

					args = args.Replace("%1", uri.OriginalString);

					try
					{
						Process.Start(exePath, args);
						return true;
					}
					catch
					{
						// do nothing.
					}
				}
			}

			/*Another method*/
			//You can only call executables (.exe) if you set UseShellExecute to
			//false. To run a dll when UseShellExecute is false, you can use
			//"rundll32" to do this as in:

			//Process myProcess = new Process();
			//ProcessStartInfo myProcessStartInfo = 
			//new ProcessStartInfo("rundll32.exe" );
			//myProcessStartInfo.UseShellExecute = false;
			//myProcessStartInfo.RedirectStandardOutput = true;
			//myProcessStartInfo.Arguments= "url.dll ,FileProtocolHandler
			//www.microsoft.com";
			//myProcess.StartInfo = myProcessStartInfo;
			//myProcess.Start();

			//Warning: If you try to start the process "http://www.microsoft.com" from
			//a [MTAThreaded] application with UseShellExecute set to true, your
			//[MTAThreaded] application will throw an exception.

			//Regards,
			//Jeff


			return false;
		}

		private static string GetDefaultBrowserCommand()
		{
			RegistryKey key = null;

			try
			{
				/*Note that we may not have permission to open the key.*/
				key = Registry.ClassesRoot.OpenSubKey(@"HTTP\shell\open\command", false);

				/*Gets default value of the key*/
				return key.GetValue(null).ToString();
			}
			catch
			{
				return null;
			}
			finally
			{
				if (key != null)
				{
					key.Close();
				}
			}
		}
	}
}
